package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.ApArticleConfigService;
import com.heima.article.service.ApArticleContentService;
import com.heima.article.service.ApArticleService;
import com.heima.common.constants.article.ArticleConstants;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.article.dtos.ArticleHomeDto;
import com.heima.model.article.dtos.ArticleInfoDto;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.article.pojos.ApArticleContent;
import com.heima.model.article.vo.HotArticleVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import org.apache.commons.collections.map.HashedMap;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements ApArticleService {

    @Autowired
    private ApArticleConfigService apArticleConfigService;

    @Autowired
    private ApArticleContentService apArticleContentService;

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public ResponseResult saveApArticle(ArticleDto dto) {
        //1.判断参数
        if(dto==null){
            ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //2.拷贝dto给apArticle
        ApArticle apArticle = new ApArticle();
        BeanUtils.copyProperties(dto,apArticle);

        //3.根据ID判断，如果无值就创建
        if(apArticle.getId()==null || apArticle.getId()==0){
            //保存ap_article
            save(apArticle);

            //保存ap_article_config
            ApArticleConfig apArticleConfig = new ApArticleConfig();
            apArticleConfig.setArticleId(apArticle.getId());
            apArticleConfig.setIsDelete(false);//未删除
            apArticleConfig.setIsDown(false);//未下架
            apArticleConfig.setIsComment(true);//允许评论
            apArticleConfig.setIsForward(true);//允许转发
            apArticleConfigService.save(apArticleConfig);

            //保存ap_article_content
            ApArticleContent apArticleContent = new ApArticleContent();
            apArticleContent.setArticleId(apArticle.getId());
            apArticleContent.setContent(dto.getContent());//文章内容
            apArticleContentService.save(apArticleContent);
        } else { //4.如果有值就更新

            //判断文章是否存在
            ApArticle apArticleDB = getById(apArticle.getId());
            if(apArticleDB==null){
                return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "文章不存在不能更新");
            }
            //更新ap_article
            updateById(apArticle);

            //更新ap_article_content
            apArticleContentService.update(Wrappers.<ApArticleContent>lambdaUpdate()
                    .eq(ApArticleContent::getArticleId,apArticle.getId()) //更新条件
                    .set(ApArticleContent::getContent, dto.getContent())); //要更新的字段
        }



        //5.导入文章数据到ES
        Map articleMap = new HashedMap(); //每一条要导入到ES中的文章
        articleMap.put("publishTime", apArticle.getPublishTime());//发布时间
        articleMap.put("layout", apArticle.getLayout());//布局方式
        articleMap.put("images", apArticle.getImages());//封面图片
        articleMap.put("authorId", apArticle.getAuthorId());//作者ID
        articleMap.put("title", apArticle.getTitle());//文章标题


        IndexRequest indexRequest = new IndexRequest("app_info_article");
        indexRequest.source(articleMap).id(String.valueOf(apArticle.getId()));

        try {
            restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }


        //5.将APP文章ID响应回去
        return ResponseResult.okResult(apArticle.getId());
    }

    @Autowired
    private ApArticleMapper apArticleMapper;

    @Value("${file.oss.web-site}")
    private String webSite; //OOS域名


    @Override
    public ResponseResult load(ArticleHomeDto dto, Short type) {
        //1.判断参数
        if(dto==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //2.判断并处理type默认值
        if(!type.equals(ArticleConstants.LOADTYPE_LOAD_MORE) && !type.equals(ArticleConstants.LOADTYPE_LOAD_NEW)){
            type = ArticleConstants.LOADTYPE_LOAD_MORE; //默认加载更多
        }

        //3.判断size并处理默认值
        if(dto.getSize()==null || dto.getSize()<=0){
            dto.setSize(10); //默认查询10条
        }
        dto.setSize(Math.min(dto.getSize(),50)); //最大不超50条

        //4.判断maxBehotTime并处理默认值
        if(dto.getMaxBehotTime()==null) dto.setMaxBehotTime(new Date());

        //5.判断minBehotTime并处理默认值
        if(dto.getMinBehotTime()==null) dto.setMinBehotTime(new Date());

        //6.判断tag并处理默认值
        if(StringUtils.isBlank(dto.getTag())){
            dto.setTag(ArticleConstants.DEFAULT_TAG); //默认推荐频道
        }

        //7.调用mapper查询文章列表
        List<ApArticle> apArticleList = apArticleMapper.loadArticleList(dto, type);

        //8.并装响应结果设置host
        ResponseResult responseResult = ResponseResult.okResult(apArticleList);
        responseResult.setHost(webSite);

        //9.响应数据
        return responseResult;
    }

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Override
    public ResponseResult load(ArticleHomeDto dto, Short type, Boolean isFromIndex) {
        if(isFromIndex){
            String json = stringRedisTemplate.opsForValue().get(ArticleConstants.HOT_ARTICLE_FIRST_PAGE + dto.getTag());
            List<HotArticleVo> hotArticleVoList = JSON.parseArray(json, HotArticleVo.class);
            ResponseResult responseResult = ResponseResult.okResult(hotArticleVoList);
            responseResult.setHost(webSite);
            return responseResult;
        } else {
            return load(dto,type);
        }
    }

    @Override
    public ResponseResult loadInfo(ArticleInfoDto dto) {
        //1.判断参数
        if(dto==null || dto.getArticleId()==null || dto.getArticleId()==0){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //2.根据文章ID查询配置判断是否存在
        ApArticleConfig config = apArticleConfigService.getOne(Wrappers.<ApArticleConfig>lambdaQuery().eq(ApArticleConfig::getArticleId, dto.getArticleId()));
        if(config==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "文章配置不存在");
        }

        //3.判断文章状态是否是已下架或已删除
        if(config.getIsDelete() || config.getIsDown()){
            return ResponseResult.errorResult(AppHttpCodeEnum.LOGIC_ERROR, "文章状态不对");
        }

        //4.根据文章ID查询文章内容
        ApArticleContent content = apArticleContentService.getOne(Wrappers.<ApArticleContent>lambdaQuery().eq(ApArticleContent::getArticleId, dto.getArticleId()));

        //5.封装响应数据
        Map map = new HashMap<>();
        map.put("config", config);
        map.put("content", content);
        ResponseResult responseResult = ResponseResult.okResult(map);
        responseResult.setHost(webSite);

        //6.响应数据
        return responseResult;
    }
}